package com.blogs.common.utils;

import com.blogs.common.constant.WebConst;
import com.blogs.domain.db.SysUser;
import com.blogs.web.controller.admin.AttachController;
import org.apache.commons.lang3.StringUtils;
import org.commonmark.Extension;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.node.Node;
import org.commonmark.renderer.html.HtmlRenderer;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 工具类
 *
 * @author hubiao
 */
public class TaleUtils {

    /**
     * 匹配邮箱正则
     */
    private static final Pattern VALID_EMAIL_ADDRESS_REGEX =
            Pattern.compile( "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE );
    private static final Pattern SLUG_REGEX = Pattern.compile( "^[A-Za-z0-9_-]{5,100}$", Pattern.CASE_INSENSITIVE );

    /**
     * 获取session中的用户
     *
     * @param request
     * @return
     */
    public static SysUser getLoginUser(HttpServletRequest request) {
        HttpSession session = request.getSession();
        if (null == session) {
            return null;
        }
        return (SysUser) session.getAttribute( WebConst.LOGIN_SESSION_KEY );
    }

    /**
     * 获取cookie中的用户ID
     *
     * @param request
     * @return
     */
    public static Integer getCookieUid(HttpServletRequest request) {
        if (null != request) {
            Cookie cookie = cookieRaw( WebConst.USER_IN_COOKIE, request );
            if (cookie != null && cookie.getValue() != null) {
                try {
                    String uid = Tools.deAes( cookie.getValue(), WebConst.AES_SALT );
                    return StringUtils.isNotBlank( uid ) && Tools.isNumber( uid ) ? Integer.valueOf( uid ) : null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 从cookies中获取指定cookie
     *
     * @param name    名称
     * @param request 请求
     * @return cookie
     */
    private static Cookie cookieRaw(String name, HttpServletRequest request) {
        Cookie[] servletCookies = request.getCookies();
        if (servletCookies == null) {
            return null;
        }
        for (Cookie c : servletCookies) {
            if (c.getName().equals( name )) {
                return c;
            }
        }
        return null;
    }

    /**
     * 设置记住密码cookie
     *
     * @param response
     * @param uid
     */
    public static void setCookie(HttpServletResponse response, Integer uid) {
        try {
            String val = Tools.enAes( uid.toString(), WebConst.AES_SALT );
            boolean isSSL = false;
            Cookie cookie = new Cookie( WebConst.USER_IN_COOKIE, val );
            cookie.setPath( "/" );
            cookie.setMaxAge( 60 * 30 );
            cookie.setSecure( isSSL );
            response.addCookie( cookie );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取保存文件的位置，jar所在的目录的路径
     *
     * @return
     */
    public static String getUploadFilePath() {
        String path = TaleUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        path = path.substring( 1, path.length() );
        try {
            java.net.URLDecoder.decode( path, "UTF-8" );
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        int lastIndex = path.lastIndexOf( "/" ) + 1;
        path = path.substring( 0, lastIndex );
        File file = new File( "" );
        return file.getAbsolutePath() + "/";
    }

    public static String getFileKey(String name) {
        String prefix = "/upload/" + DateKit.dateFormat( new Date(), "yyyy/MM" );
        if (!new File( AttachController.CLASSPATH + prefix ).exists()) {
            new File( AttachController.CLASSPATH + prefix ).mkdirs();
        }
        name = StringUtils.trimToNull( name );
        if (name == null) {
            return prefix + "/" + UUID.UU32() + "." + null;
        } else {
            name = name.replace( '\\', '/' );
            name = name.substring( name.lastIndexOf( "/" ) + 1 );
            int index = name.lastIndexOf( "." );
            String ext = null;
            if (index > 0) {
                ext = StringUtils.trimToNull( name.substring( index + 1 ) );
            }
            return prefix + "/" + UUID.UU32() + "." + (ext == null ? null : (ext));
        }
    }

    /**
     * 判断文件是否是图片类型
     *
     * @param imageFile
     * @return
     */
    public static boolean isImage(InputStream imageFile) {
        try {
            Image img = ImageIO.read( imageFile );
            if (img == null || img.getWidth( null ) <= 0 || img.getHeight( null ) <= 0) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;

        }
    }

    /**
     * MD5加密
     *
     * @param source 数据源
     * @return 加密字符串
     */
    public static String MD5encode(String source) {
        if (StringUtils.isBlank( source )) {
            return null;
        }
        MessageDigest messageDigest = null;

        try {
            // 得到一个信息摘要器
            messageDigest = MessageDigest.getInstance( "MD5" );
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        byte[] encode = messageDigest.digest( source.getBytes() );
        StringBuffer hexString = new StringBuffer();
        // 把每一个byte 做一个与运算 0xff;
        for (byte anEncode : encode) {
            // 与运算  加盐
            String hex = Integer.toHexString( 0xff & anEncode );
            if (hex.length() == 1) {
                hexString.append( "0" );
            }
            hexString.append( hex );
        }
        // 标准的md5加密后的结果
        return hexString.toString();

    }

    /**
     * markdown转换为html
     *
     * @param markdown
     * @return
     */
    public static String mdToHtml(String markdown) {
        if (StringUtils.isBlank( markdown )) {
            return "";
        }
        java.util.List<Extension> extensions = Arrays.asList( TablesExtension.create() );
        org.commonmark.parser.Parser parser = org.commonmark.parser.Parser.builder().extensions( extensions ).build();
        Node document = parser.parse( markdown );
        HtmlRenderer renderer = HtmlRenderer.builder().extensions( extensions ).build();
        String content = renderer.render( document );
        content = Commons.emoji( content );
        return content;

    }

    /**
     * 判断是否是邮箱
     *
     * @param emailStr
     * @return
     */
    public static boolean isEmail(String emailStr) {
        Matcher matcher = VALID_EMAIL_ADDRESS_REGEX.matcher( emailStr );
        return matcher.find();
    }

    /**
     * 验证URL地址
     *
     * @param url 格式：http://blog.csdn.net:80/xyang81/article/details/7705960? 或 http://www.csdn.net:80
     * @return 验证成功返回true，验证失败返回false
     */
    public static boolean isURL(String url) {
        String regex = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?";
        return Pattern.matches( regex, url );
    }

    /**
     * 替换HTML脚本
     *
     * @param value
     * @return
     */
    public static String cleanXSS(String value) {
        //You'll need to remove the spaces from the html entities below
        value = value.replaceAll( "<", "&lt;" ).replaceAll( ">", "&gt;" );
        value = value.replaceAll( "\\(", "&#40;" ).replaceAll( "\\)", "&#41;" );
        value = value.replaceAll( "'", "&#39;" );
        value = value.replaceAll( "eval\\((.*)\\)", "" );
        value = value.replaceAll( "[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"" );
        value = value.replaceAll( "script", "" );
        return value;
    }
}
